package cn.e4j.core.mybatis_plus;

import cn.e4j.core.shiro.ShiroKit;
import cn.e4j.core.shiro.ShiroUser;
import cn.e4j.core.util.DateUtils;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * mybatis-plus 自动填值, 需要在 entity里面加注释
 *
 * @author wenchuan.li
 * @date 2018/12/13 14:25
 */
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    private long _id = 0;

    @Override
    public synchronized void insertFill(MetaObject metaObject) {

        long time = System.currentTimeMillis();
        if (time != _id && time > _id) {
            _id = time;
        } else {
            _id += 1;
        }

        Map<String, Object> fieldMaps = new HashMap<>();

        fieldMaps.put("ID", _id + "");

        LocalDateTime _dateTime = LocalDateTime.now();
        fieldMaps.put("CREATE_TIME", _dateTime);
        fieldMaps.put("CREATE_DATE", _dateTime);
        fieldMaps.put("UPDATE_DATE", _dateTime);

        ShiroUser shiroUser = ShiroKit.getUser();
        if (null != shiroUser) {
            fieldMaps.put("CREATE_BY", shiroUser.getID());
            fieldMaps.put("UPDATE_BY", shiroUser.getID());
        }

        String classNm = "";
        if (metaObject.hasGetter("et")) {
            Object et = metaObject.getValue("et");
            if (et != null) {
                classNm = et.getClass().getSimpleName();
            }
        } else {
            classNm = metaObject.getOriginalObject().getClass().getSimpleName();
        }

        if(null!=shiroUser){
            classNm = classNm.substring(0, classNm.length() - 1).toUpperCase();
            fieldMaps.put(classNm + "USER", shiroUser.getID());
            fieldMaps.put(classNm + "GRUP", shiroUser.getORG_ID());
            fieldMaps.put(classNm + "TIME", DateUtils.getTime());
            fieldMaps.put(classNm + "DATE", LocalDate.now());
            fieldMaps.put(classNm + "ORIG", shiroUser.getORG_ID());
            fieldMaps.put(classNm + "ORIU", shiroUser.getID());
        }

        setFieldValByName(fieldMaps, metaObject);

    }

    public MetaObjectHandler setFieldValByName(Map<String, Object> fieldMaps, MetaObject metaObject) {
        MetaObject etMeta = null;

        if (metaObject.hasGetter("et")) {
            Object et = metaObject.getValue("et");
            if (et != null) {
                etMeta = SystemMetaObject.forObject(et);
            }
        }

        for (Map.Entry<String, Object> entry : fieldMaps.entrySet()) {
            String fieldName = entry.getKey();
            Object fieldVal = entry.getValue();
            if (metaObject.hasSetter(fieldName) && metaObject.hasGetter(fieldName)) {
                metaObject.setValue(fieldName, fieldVal);
            } else if (etMeta != null && etMeta.hasSetter(fieldName)) {
                etMeta.setValue(fieldName, fieldVal);
            }
        }

        return this;
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        Map<String, Object> fieldMaps = new HashMap<>();
        LocalDateTime _date = LocalDateTime.now();
        //fieldMaps.put("UPDATE_DATE", _date);

        ShiroUser shiroUser = ShiroKit.getUser();
        if (null != shiroUser) {
            //fieldMaps.put("UPDATE_BY", shiroUser.getID());
        }


        String classNm = "";
        if (metaObject.hasGetter("et")) {
            Object et = metaObject.getValue("et");
            if (et != null) {
                classNm = et.getClass().getSimpleName();
            }
        } else {
            classNm = metaObject.getOriginalObject().getClass().getSimpleName();
        }

        if(null!=shiroUser){
            classNm = classNm.substring(0, classNm.length() - 1).toUpperCase();
            fieldMaps.put(classNm + "MODU", shiroUser.getID());
        }
        setFieldValByName(fieldMaps, metaObject);
    }

}
